﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PlaceHR.Processor.Processor
{
    public class SalaryEngine : EngineBase
    {
        public SalaryEngine(int year, int month, int day)
        {
            this.Year = year;
            this.Month = month;
            this.Day = day;
        }

        public override string EngineName
        {
            get
            {
                return Constants.SalaryTypeCode;
            }
        }

        public override void Run()
        {
            Record = HRDBContext.ProcessorRecord.FirstOrDefault(p => p.Year == this.Year
                            && p.Month == this.Month //&& p.Day == this.Day
                            && p.ProcessorTypeCode != null
                            && p.ProcessorTypeCode.Equals(EngineName, StringComparison.OrdinalIgnoreCase));

            if (Record == null)
            {
                Record = new ProcessorRecord
                {
                    ProcessorTypeCode = EngineName,
                    Year = this.Year,
                    Month = this.Month,
                    //Day = this.Day,
                    ProcessorStatusCode = ProcessorStatusCode.Pending,
                    InsertDate = DateTime.Now,
                    UpdateDate = DateTime.Now,
                    UpdateBy = -1
                };

                HRDBContext.ProcessorRecord.AddObject(Record);
                HRDBContext.SaveChanges();
            }

            if (Record.ProcessorStatusCode.Equals(ProcessorStatusCode.Pending, StringComparison.OrdinalIgnoreCase) || this.ForceRecalculate)
            {
                Console.WriteLine(string.Format("开始计算{0}年{1}月工资...", this.Year, this.Month));
                // begin or continue to process employee salary
                this.ProcessEmployeeSalary();

                Record.ProcessorStatusCode = ProcessorStatusCode.Succeed;
                Record.UpdateDate = DateTime.Now;
                HRDBContext.SaveChanges();

                this.LogEvent("Salary Auto Engine", string.Format("{0}年{1}月份工资计算完毕！", this.Year, this.Month));
            }
            else
            {
                Console.WriteLine(string.Format("{0}年{1}月工资数据已存在，退出计算！", this.Year, this.Month));
            }
        }

        #region Private Methods

        private void ProcessEmployeeSalary()
        {
            var employeeList = HRDBContext.Employee.Where(p => !p.IsDeleted
                && p.StatusCode != null
                && p.StatusCode.Equals(EmployeeStatusCode.Regular, StringComparison.OrdinalIgnoreCase)).ToList();
                //&& !p.EmployeeSalary.Any(s => s.Year.Value == Year && s.Month.Value == Month && !s.IsDeleted)

            if (employeeList == null || employeeList.Count < 1)
            {
                return;
            }

            foreach (var employee in employeeList)
            {
                try
                {
                    var processor = new SalaryProcessor();
                    processor.Init(employee, this);
                    processor.Process();
                }
                catch (Exception ex)
                {
                    this.LogEvent("Salary Calculate Error", ex.Message);
                }

            }
        }

        #endregion

    }
}
